/**
 * 
 */
package com.zgz.underwrite.service.impl;

import ilog.rules.res.session.IlrSessionRequest;
import ilog.rules.res.session.IlrSessionResponse;

import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;

import com.zgz.underwrite.dto.ApplicantDTO;
import com.zgz.underwrite.dto.CoverageDTO;
import com.zgz.underwrite.dto.InsuranceAppDTO;
import com.zgz.underwrite.dto.InsurantDTO;
import com.zgz.underwrite.dto.InsuredCvrgDTO;
import com.zgz.underwrite.dto.PremiumCoefDTO;
import com.zgz.underwrite.dto.SpecialConventionDTO;
import com.zgz.underwrite.dto.UnderwriteResultDTO;
import com.zgz.underwrite.dto.VehicleDTO;
import com.zgz.underwrite.dto.VhlDriverDTO;
import com.zgz.underwrite.dto.VhlOwnerDTO;
import com.zgz.underwrite.model.Coverage;
import com.zgz.underwrite.model.InsuranceApplication;
import com.zgz.underwrite.model.InsuredCvrg;
import com.zgz.underwrite.model.SpecialConvention;
import com.zgz.underwrite.service.PremiumService;
import com.zgz.underwrite.util.CalPremiumHelper;
import com.zgz.underwrite.util.ILogUtil;

/**
 * @author zgz
 *
 */
public class PremiumServiceImpl implements PremiumService{

	private final static Logger log = Logger.getLogger(PremiumServiceImpl.class);
	
	@Override
	public void calPremium(InsuranceApplication app) throws Exception {
		UnderwriteResultDTO underwriteResultDTO = null;
//		Set<InsuredCvrg> newinsuredCvrgs = new HashSet();
		Set<InsuredCvrg> insuredCvrgs = app.getInsuredCvrg();
		CalPremiumHelper calPremiumHelper = new CalPremiumHelper(app.getPremiumCoef());
		Double basePrm = 0.0;
		for(Iterator<InsuredCvrg> it = insuredCvrgs.iterator();it.hasNext();){
			InsuredCvrg insuredCvrg = (InsuredCvrg) it.next();
			underwriteResultDTO = this.remoteEJBCallILogRules(app,insuredCvrg.getCvrg());//调用规则
			basePrm = underwriteResultDTO.getPremiumMap().get(insuredCvrg.getCvrg().getSCvrgNo());
			insuredCvrg.setNBasePrm(basePrm);
			insuredCvrg.setNRate(basePrm);
			insuredCvrg.setNBefPrm(basePrm);
			insuredCvrg.setNDisCoef(calPremiumHelper.getTrafTolCoef());
			insuredCvrg.setNPremium(calPremiumHelper.getTrafPrem(basePrm));
		}
	}

	private UnderwriteResultDTO remoteEJBCallILogRules(InsuranceApplication app,Coverage cvrg) throws Exception{
		IlrSessionRequest req = ILogUtil.getDefltIlrSessionRequest();
		InsuranceAppDTO appDTO = new InsuranceAppDTO();
		this.changeModelToDTO(app, appDTO);
		CoverageDTO cvrgDTO = this.getCvrgDTO(cvrg);
		req.setInputParameter("insuranceAppDTO", appDTO);
		req.setInputParameter("underwriteResultDTO", new UnderwriteResultDTO());
//		req.setInputParameter("ruleFlowControllerDTO", this.getRuleController(app));
		req.setInputParameter("modelType", "保费计算");
		req.setInputParameter("cvrgDTO", cvrgDTO);
		req.setTraceEnabled(true);
		req.setForceUptodate(true);
		IlrSessionResponse resp = ILogUtil.getIlrStatelessSession().execute(req);
		UnderwriteResultDTO underwriteResultDTO = (UnderwriteResultDTO) resp.getOutputParameters().get("underwriteResultDTO");
		log.info(ILogUtil.getExecTraceReslt(resp));
		return underwriteResultDTO;
	}
	
	private CoverageDTO getCvrgDTO(Coverage cvrg)throws Exception{
		CoverageDTO coverageDTO = new CoverageDTO();
		BeanUtils.copyProperties(coverageDTO, cvrg);
		return coverageDTO;
	}
	
	
	/**
	 * 规则流控制器
	 * @param app
	 * @return
	 */
//	private RuleFlowControllerDTO getRuleController(InsuranceApplication app){
//		RuleFlowControllerDTO ruleFlowControllerDTO = new RuleFlowControllerDTO();
//		ruleFlowControllerDTO.setSDeptNo(app.getDepartment().getSDeptNo());
//		ruleFlowControllerDTO.setSModelType("保费计算");
//		ruleFlowControllerDTO.setSProductNo(app.getProduct().getSProductCde());
//		return 	ruleFlowControllerDTO;
//	}
	
	
	
	/**
	 * 把领域模型的成员拷贝到DTO
	 * @param app
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	private void changeModelToDTO(InsuranceApplication app,InsuranceAppDTO appDTO) throws IllegalAccessException, InvocationTargetException{
		//TODO 还有些属性没拷贝
		BeanUtils.copyProperties(appDTO, app);
		
		VehicleDTO vehicleDTO = new VehicleDTO();
		BeanUtils.copyProperties(vehicleDTO, app.getVehicle());
		VhlOwnerDTO vhlOwnerDTO = new VhlOwnerDTO();
		VhlDriverDTO vhlDriverDTO = new VhlDriverDTO();
		BeanUtils.copyProperties(vhlOwnerDTO, app.getVehicle().getVhlOwner());
		BeanUtils.copyProperties(vhlDriverDTO, app.getVehicle().getVhlDriver());
		vehicleDTO.setVhlDriverDTO(vhlDriverDTO);
		vehicleDTO.setVhlOwnerDTO(vhlOwnerDTO);
		
		
		ApplicantDTO applicantDTO = new ApplicantDTO();
		BeanUtils.copyProperties(applicantDTO, app.getApplicant());
		
		InsurantDTO insurantDTO = new InsurantDTO();
		BeanUtils.copyProperties(insurantDTO, app.getInsurant());
		
		PremiumCoefDTO premiumCoefDTO = new PremiumCoefDTO();
		BeanUtils.copyProperties(premiumCoefDTO, app.getPremiumCoef());
		
		
		Set<InsuredCvrg> insuredCvrgs = app.getInsuredCvrg();
		Set<InsuredCvrgDTO> insuredCvrgsDTO = new HashSet<InsuredCvrgDTO>();
		InsuredCvrgDTO insuredCvrgDTO = null;
		for(Iterator<InsuredCvrg> it = insuredCvrgs.iterator();it.hasNext();){
			InsuredCvrg insuredCvrg = (InsuredCvrg) it.next();
			insuredCvrgDTO = new InsuredCvrgDTO();
			BeanUtils.copyProperties(insuredCvrgDTO,insuredCvrg);
			insuredCvrgsDTO.add(insuredCvrgDTO);
		}
		
		Set<SpecialConvention> specConventions = app.getSpecConventions();
		Set<SpecialConventionDTO> specConventionsDTO = new HashSet<SpecialConventionDTO>();
		for(Iterator<SpecialConvention> it = specConventions.iterator();it.hasNext();){
			SpecialConvention spec = (SpecialConvention) it.next();
			SpecialConventionDTO specialConventionDTO = new SpecialConventionDTO();
			BeanUtils.copyProperties(specialConventionDTO, spec);
			specConventionsDTO.add(specialConventionDTO);
		}
		
		
		appDTO.setVehicleDTO(vehicleDTO);
		appDTO.setApplicantDTO(applicantDTO);
		appDTO.setInsurantDTO(insurantDTO);
		appDTO.setPremiumCoefDTO(premiumCoefDTO);
		appDTO.setInsuredCvrgsDTO(insuredCvrgsDTO);
		appDTO.setSpecConventionsDTO(specConventionsDTO);
		
		appDTO.setSDepartment(app.getDepartment().getSDeptName());
		appDTO.setSBusinessMan(app.getBusinessMan().getSEmpName());
		appDTO.setSEntering(app.getEntering().getSEmpName());
		appDTO.setSProduct(app.getProduct().getSProductName());
	}

}
